// EasyHookLib.inl - 模板实现文件
// 注意：这个文件在 EasyHookLib.h 的命名空间内被包含，所以不要再嵌套命名空间

#include "MinHook.h"

// HookManager模板方法实现
template<typename FuncType>
bool HookManager::createHook(FuncType targetFunc, FuncType detourFunc, FuncType *originalFunc)
{
    if (!initialized_ && !initialize())
    {
        return false;
    }

    MH_STATUS status = MH_CreateHook(reinterpret_cast<LPVOID>(targetFunc), reinterpret_cast<LPVOID>(detourFunc), reinterpret_cast<LPVOID *>(originalFunc));

    if (status != MH_OK)
    {
        setError("Failed to create hook: " + statusToString(status));
        return false;
    }

    status = MH_EnableHook(reinterpret_cast<LPVOID>(targetFunc));
    if (status != MH_OK)
    {
        setError("Failed to enable hook: " + statusToString(status));
        return false;
    }

    hooks_.push_back(reinterpret_cast<LPVOID>(targetFunc));
    return true;
}

// Hook类模板实现
template<typename FuncType>
Hook<FuncType>::Hook(FuncType targetFunc, FuncType detourFunc)
    : target_(targetFunc)
    , detour_(detourFunc)
    , original_(nullptr)
    , enabled_(false)
{
    auto &manager = HookManager::getInstance();
    if (manager.createHook(targetFunc, detourFunc, &original_))
    {
        enabled_ = true;
    }
}

template<typename FuncType>
Hook<FuncType>::Hook(const std::string &moduleName, const std::string &funcName, FuncType detourFunc)
    : target_(nullptr)
    , detour_(detourFunc)
    , original_(nullptr)
    , enabled_(false)
{
    auto &manager = HookManager::getInstance();
    if (manager.createAPIHook(moduleName, funcName, reinterpret_cast<LPVOID>(detourFunc), reinterpret_cast<LPVOID *>(&original_)))
    {
        enabled_ = true;
    }
}

// ================================
// 新增：通过偏移构造Hook
// ================================
template<typename FuncType>
Hook<FuncType>::Hook(const std::string &moduleName, DWORD offset, FuncType detourFunc)
    : target_(nullptr)
    , detour_(detourFunc)
    , original_(nullptr)
    , enabled_(false)
{
    auto &manager = HookManager::getInstance();

    // 获取目标地址
    LPVOID targetAddr = manager.GetAddressByOffset(moduleName, offset);
    if (targetAddr)
    {
        target_ = reinterpret_cast<FuncType>(targetAddr);

        // 创建Hook
        if (manager.createOffsetHook(moduleName, offset, reinterpret_cast<LPVOID>(detourFunc), reinterpret_cast<LPVOID *>(&original_)))
        {
            enabled_ = true;
        }
    }
}

template<typename FuncType>
Hook<FuncType>::~Hook()
{
    if (enabled_ && target_)
    {
        MH_DisableHook(reinterpret_cast<LPVOID>(target_));
    }
}